﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using System.IO;
using ICSharpCode.SharpZipLib.Zip;
using System.Text.RegularExpressions;
using System.Xml.Serialization;
using eDonkeyAPI.Models;
using System.Web;


namespace eDonkeyAPI.Controllers
{
    public class RepController : ApiController
    {
        /*
         * Use this api to add tables in the database on the website (tdonkey.yudapps.com)
         */ 
        [HttpGet]
        public void CreateTable()
        {
            mydbEntities myDB = new mydbEntities();
            myDB.Database.ExecuteSqlCommand("Drop TABLE Users");
            //myDB.Database.ExecuteSqlCommand("CREATE TABLE Users (id int, [User] VARCHAR(MAX), URL VARCHAR(MAX))");
            myDB.Database.ExecuteSqlCommand("CREATE TABLE [dbo].[Users] ( [Id]   INT NOT NULL, [User] VARCHAR (MAX) NULL, [URL]  VARCHAR (MAX) NULL, CONSTRAINT [PK_Users] PRIMARY KEY CLUSTERED ([Id] ASC));");
        }

        [HttpGet]
        public void Rep2DB()
        {
            string RepPath = HttpContext.Current.Server.MapPath("~/REPY");
            string XmlPath = HttpContext.Current.Server.MapPath("~/myXML.xml");
            if(File.Exists(RepPath))
                File.Delete(RepPath);
            if(File.Exists(XmlPath))
                File.Delete(XmlPath);
            GetRep();
            Rep2XML();
            removeSemester();
            XML2DB();
            File.Delete(RepPath);
            File.Delete(XmlPath);
        }

        private void OpenZipStream(Stream strm)
        {
            ZipInputStream s = new ZipInputStream(strm);
            ZipEntry theEntry; // A file inside the zip
            while ((theEntry = s.GetNextEntry()) != null)
            {

                Console.WriteLine(theEntry.Name);

                string directoryName = Path.GetDirectoryName(theEntry.Name);
                string fileName = Path.GetFileName(theEntry.Name);

                if (fileName != String.Empty)
                {
                    FileStream streamWriter = File.Create(HttpContext.Current.Server.MapPath("~/REPY"));

                    int size = 2048;
                    byte[] data = new byte[2048]; // Read buffer
                    while (true) // Loop to read the entire file from the stream
                    {
                        size = s.Read(data, 0, data.Length);
                        if (size > 0)
                        {
                            streamWriter.Write(data, 0, size);
                        }
                        else
                        {
                            break;
                        }
                    }

                    streamWriter.Close();
                }
            }
            s.Close(); // Close the Zip File
            //???File.Delete(m_zipFileName); // Delete the Zip File
            return;
        }

        [HttpGet]
        public string GetRep(string url = "http://ug.technion.ac.il/rep/REPFILE.zip")
        {            
            System.Net.WebClient Client = new System.Net.WebClient();
            Stream strm;
            try
            {
                strm = Client.OpenRead(url);
            }
            catch (System.Net.WebException)
            {
                return null;
            }
            OpenZipStream(strm);
            return null;
        }

        [HttpGet]
        public string Rep2XML()
        {
            /*TODO:
             * remove old xml file
             * convert rep to xml
             */

            RepToXML.Convert(HttpContext.Current.Server.MapPath("~/REPY"), HttpContext.Current.Server.MapPath("~/myXML.xml"));
            return null;
        }

        private DateTime parseMoedDate(string moed)
        {
            if (moed == null || moed == "")
                return new DateTime();
            if(moed.Contains(" "))
                moed = moed.Split(' ')[1];
            string[] s = moed.Split('/');
            if(s.Length != 3)
                return new DateTime();
            DateTime dt = new DateTime(Convert.ToInt32(s[0]), Convert.ToInt32(s[1]), Convert.ToInt32(s[2]));
            return dt;
        }

        //This will remove all courses/groups/placesAndTimes/Teachers in the Database.
        private void removeSemester()
        {
            mydbEntities myDB = new mydbEntities();
            foreach(Course c in myDB.Courses.ToList<Course>()){
                myDB.Courses.Remove(c);
            }
            foreach (eDonkeyAPI.Models.Group g in myDB.Groups.ToList<eDonkeyAPI.Models.Group>())
            {
                myDB.Groups.Remove(g);
            }
            foreach (Teacher t in myDB.Teachers.ToList<Teacher>())
            {
                myDB.Teachers.Remove(t);
            }
            foreach (PlaceTime pt in myDB.PlaceTimes.ToList<PlaceTime>())
            {
                myDB.PlaceTimes.Remove(pt);
            }
            myDB.SaveChanges();
        }


        [HttpGet]
        public void XML2DB(string faculty="")
        {
            
            mydbEntities myDB = new mydbEntities();

            int courseId;
            try
            {
                courseId = myDB.Courses.Select(c => c.Id).Max();
            }
            catch
            {
                courseId = 0;
            }

            int teacherId;
            try
            {
                teacherId = myDB.Teachers.Select(t => t.Id).Max();
            }
            catch
            {
                teacherId = 0;
            }

            int groupId = 0;
            try
            {
                groupId = myDB.Groups.Select(g => g.Id).Max();
            }
            catch
            {
                if (myDB.Groups.Select(g => g.Id) == null)
                {
                    groupId = 0;
                }
            }
            int PlaceTimeId = 0;
            try
            {
                PlaceTimeId = myDB.PlaceTimes.Select(pt => pt.Id).Max();
            }
            catch
            {
                if (myDB.PlaceTimes.Select(pt => pt.Id) == null)
                {
                    PlaceTimeId = 0;
                }
            }
            XmlSerializer ser = new XmlSerializer(typeof(CourseDB));
            FileStream xmlFile = File.OpenRead(HttpContext.Current.Server.MapPath("~/myXML.xml"));
            CourseDB db = (CourseDB)ser.Deserialize(xmlFile);
            
                foreach (CourseDBFaculty f in db.Items)
                {
                        foreach (CourseDBFacultyCourse c in f.Course)
                        {
                            Course newCourse = new Course();
                            newCourse.Faculty = f.name;
                            newCourse.Id = (++courseId);
                            Teacher teacher;
                            teacher = myDB.Teachers.FirstOrDefault(t => t.FirstName == c.lecturerInCharge);
                            if (teacher == null)
                            {
                                teacher = new Teacher();
                                teacher.Id = (++teacherId);
                                teacher.FirstName = c.lecturerInCharge;
                                myDB.Teachers.Add(teacher);
                                myDB.SaveChanges();
                            }
                            newCourse.LecturerId = teacher.Id;
                            newCourse.Name = c.name;
                            newCourse.Number = c.number;
                            if (c.courseAcademicPoints != "")
                                newCourse.Points = Convert.ToDouble(c.courseAcademicPoints);
                            else
                                newCourse.Points = 0;
                            newCourse.SemesterId = 1;
                            newCourse.TermA = parseMoedDate(c.moedADate);
                            newCourse.TermB = parseMoedDate(c.moedBDate);
                            myDB.Courses.Add(newCourse);
                            myDB.SaveChanges();
                            foreach (CourseDBFacultyCourseCourseEvent g in c.CourseEvent)
                            {                            
                                eDonkeyAPI.Models.Group newGroup = new eDonkeyAPI.Models.Group();
                                newGroup.CourseId = courseId;
                                newGroup.Id = (++groupId);
                                newGroup.Number = Convert.ToInt32(g.regNumber);
                                newGroup.Role = g.eventType;
                                //TODO: convert this code into function
                                teacher = myDB.Teachers.FirstOrDefault(t => t.FirstName == g.teacher);
                                if (teacher == null)
                                {
                                    teacher = new Teacher();
                                    teacher.Id = (++teacherId);
                                    teacher.FirstName = g.teacher;
                                    myDB.Teachers.Add(teacher);
                                    myDB.SaveChanges();
                                }
                                newGroup.TeacherId = teacher.Id;
                                myDB.Groups.Add(newGroup);
                                myDB.SaveChanges();
                                foreach (CourseDBFacultyCourseCourseEventPlaceTime pt in g.PlaceTime)
                                {
                                            PlaceTime newPlaceTime = new PlaceTime();
                                            newPlaceTime.Day = pt.EventDay;
                                            newPlaceTime.Duration = pt.EventDuration;
                                            newPlaceTime.GroupId = newGroup.Id;
                                            newPlaceTime.Place = pt.EventLocation;
                                            newPlaceTime.StartTime = pt.EventTime;
                                            newPlaceTime.Id = (++PlaceTimeId);
                                            myDB.PlaceTimes.Add(newPlaceTime);
                                            myDB.SaveChanges();
                                }
                            }
                            //myDB.SaveChanges();
                        }        
            }
            xmlFile.Close();
        }
    }
}
